package top.houry.netty.barrage.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import top.houry.netty.barrage.consts.BarrageRedisKeyConst;
import top.houry.netty.barrage.consts.BarrageVideoConst;
import top.houry.netty.barrage.entity.BarrageMsgSensitive;
import top.houry.netty.barrage.netty.WebSocketNettyServer;
import top.houry.netty.barrage.service.IBarrageMsgSensitiveService;
import top.houry.netty.barrage.utils.BarrageMsgSensitiveUtils;
import top.houry.netty.barrage.utils.BarrageRedisUtils;

import java.net.InetAddress;
import java.util.List;

/**
 * @Desc 抽取公共的需要在SpringBoot加载完毕之后加载的业务
 * @Author houry
 * @Date 2021/3/2 8:48
 *
 * 利用springboot的扩展机制
 **/
@Component
@Slf4j
public class BarrageServerRunner implements ApplicationRunner {

    /**
     * netty 相关
     * */
    private WebSocketNettyServer nettyServer;
    /**
     * 敏感词业务类
     * */
    private IBarrageMsgSensitiveService barrageMsgSensitiveService;
    /**
     * nacos 服务发现
     */
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Autowired
    public void setNacosDiscoveryProperties(NacosDiscoveryProperties nacosDiscoveryProperties) {
        this.nacosDiscoveryProperties = nacosDiscoveryProperties;
    }

    @Autowired
    public void setNettyServer(WebSocketNettyServer nettyServer) {
        this.nettyServer = nettyServer;
    }

    @Autowired
    public void setBarrageMsgSensitiveService(IBarrageMsgSensitiveService barrageMsgSensitiveService) {
        this.barrageMsgSensitiveService = barrageMsgSensitiveService;
    }


    @Override
    public void run(ApplicationArguments args) {
        startNetty();//启动netty
        initSensitiveMsg();//初始化敏感词
        resetOnlinePopulationNumber();//重置在线人数
        registerNameService("netty-server",nettyServer.getNettyConfigProperties().getServerPort());
    }

    private void registerNameService(String nettyName, Integer serverPort) {

        try {
            NamingService namingService = NamingFactory.createNamingService(nacosDiscoveryProperties.getServerAddr());
            InetAddress address = InetAddress.getLocalHost();
            log.info("当前服务的ip:{};port:{}",address.getHostAddress(),serverPort);
            namingService.registerInstance(nettyName, address.getHostAddress(), serverPort);
        } catch (Exception e) {
            throw new RuntimeException("nacos 注册失败");
        }
    }

    private void startNetty() {
        new Thread(() -> nettyServer.startNettyServer()).start();
    }

    private void initSensitiveMsg() {
        List<BarrageMsgSensitive> msgSensitives = barrageMsgSensitiveService.list();
        BarrageMsgSensitiveUtils.setSensitiveWords(msgSensitives);
        msgSensitives.forEach(msgSensitive -> BarrageRedisUtils.hashPut(BarrageRedisKeyConst.BARRAGE_MSG_SENSITIVE_KEY, msgSensitive.getSensitiveMsg(), msgSensitive.getShowMsg()));
    }

    /**
     *
     * 集群的话，当前逻辑，在线人数统计有问题
     * 服务1：在线人数 a
     * 服务2：在线人数 b
     * 服务n：在线人数 c
     *
     * 总在线人数：a+b+c
     */
    private void resetOnlinePopulationNumber() {
        BarrageRedisUtils.set(BarrageRedisKeyConst.BARRAGE_ONLINE_POPULATION_KEY + BarrageVideoConst.VIDE_ID, "0");
    }

}
